package io.renren.common.wxPay;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.google.common.collect.Maps;
import io.renren.common.exception.RRException;
import io.renren.common.utils.EntityUtil;
import io.renren.common.utils.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Lee
 * @description 微信支付助手封装
 * @date 2020-02-23 15:33
 **/

@Component
@Slf4j
public class WxPayHelper {

    @Autowired
    private WxConfig wxConfig;

    private WXPay wxPay;

    @Value("${baseConstant.wechatPay.notifyUrl}")
    private String NOTIFY_URL;

    private static final String wxpay_txAddress = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";

    @PostConstruct
    private void initParam() {
        this.wxPay = new WXPay(wxConfig, WXPayConstants.SignType.MD5, false);
    }

    private void validResult(Map<String, String> resultMap) {
        Boolean sta = WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("return_code"))
                && WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("result_code"));
        if (!sta) {
            if (resultMap.getOrDefault("err_code_des","微信支付").contains("付款次数超过限制")) {
                throw new RRException("当天只能提现一次",2000);
            }
            String err_code_des = resultMap.getOrDefault("err_code_des", null);
            String return_msg = resultMap.getOrDefault("return_msg", null);
            throw new RRException(StringUtils.isEmpty(err_code_des)?return_msg:err_code_des,2000);
        }
    }

    /**
     * @author Lee
     * @description 微信支付请求
     * @date 2020-02-23 16:14
     **/
    public Map<String, String> pay(WxPayReqDto payReqDto) {
        log.debug("请求微信支付参数:payReqDto:{}", JSON.toJSONString(payReqDto));
        Map<String, String> reqMap = Maps.newHashMap();
        Map<String, String> resultMap = null;
        try {
            LocalDateTime localDateTime = LocalDateTime.now();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            reqMap.put("time_start", localDateTime.format(dateTimeFormatter));
            reqMap.put("time_expire", localDateTime.plusSeconds(1800).format(dateTimeFormatter));
            reqMap.put("notify_url", NOTIFY_URL);
            reqMap.put("trade_type", "APP");
            reqMap.putAll(EntityUtil.wxEntityToStringMap(payReqDto));
            resultMap = wxPay.unifiedOrder(reqMap);
            log.info("微信下单:【{}】", resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException(e.getMessage(),2001);
        }
        validResult(resultMap);
        return resultMap;
    }

    /**
     * @author Lee
     * @description 支付单查询
     * @date 2020-02-23 17:01
     **/
    public Map<String, String> orderQuery(String orderCode) {
        Map<String, String> result;
        try {
            result = wxPay.orderQuery(new HashMap<String, String>() {{
                put("out_trade_no", orderCode);
            }});
            log.info("微信订单查询:【{}】", result);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException(e.getMessage(),2001);
        }
        validResult(result);
        return result;
    }

    /**
     * @author Lee
     * @description 微信退款
     * @date 2020-02-25 21:40
     **/
    public Map<String, String> refund(String orderCode, BigDecimal totalFee, BigDecimal refundFee) {
        Map<String, String> result;
        try {
            result = wxPay.refund(new HashMap<String, String>() {{
                put("out_trade_no", orderCode);
                put("out_refund_no", SnowflakeIdWorker.getNextOrderNo());
                put("total_fee", String.valueOf(totalFee.multiply(BigDecimal.valueOf(100)).intValue()));
                put("refund_fee", String.valueOf(refundFee.multiply(BigDecimal.valueOf(100)).intValue()));
            }});
            log.info("微信退款:【{}】", result);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException( e.getMessage(),2001);
        }
        validResult(result);
        return result;
    }

    /**
     * @author Lee
     * @description 关闭订单
     * @date 2020-02-23 17:03
     **/
    public Map<String, String> closeOrder(String orderCode) {
        Map<String, String> result;
        try {
            result = wxPay.closeOrder(new HashMap<String, String>() {{
                put("out_trade_no", orderCode);
            }});
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException(e.getMessage(),2001);
        }
        validResult(result);
        return result;
    }

    /**
     * @author Lee
     * @description 签名检查
     * @date 2020-02-23 17:03
     **/
    public Map<String, String> checkSign(String xml) {
        Map<String, String> result;
        try {
            result = wxPay.processResponseXml(xml);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException( e.getMessage(),2001);
        }
        validResult(result);
        return result;
    }


}
